﻿using Model.CommonEntities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BLL.CalRevenue
{
    public class CrossCondition
    {
        /// <summary>
        /// 多周期同步交叉买入法判断
        /// </summary>
        /// <param name="SmallTList">小周期时间列表</param>
        /// <param name="SmallLongList">小周期长期线</param>
        /// <param name="SmallShortList">小周期短期线</param>
        /// <param name="LargeTList">大周期时间列表</param>
        /// <param name="LargeLongList">大周期长期线</param>
        /// <param name="LargeShortList">大周期短期线</param>
        /// <param name="BenchmarkList">买入基准</param>
        /// <param name="CloseList">收盘价</param>
        /// <returns></returns>
        public static TotalResult DiffPeriodCross(List<decimal> SmallTList, List<decimal> SmallLongList, List<decimal> SmallShortList, List<decimal> LargeTList, List<decimal> LargeLongList, List<decimal> LargeShortList, List<decimal> BenchmarkList, List<decimal> CloseList)
        {
            //昨日交叉状态
            bool LastStatus = true;
            //今日交叉状态
            bool NowStatus = true;
            //首次买入价格
            decimal FirstPrice = 0;
            //买入价格
            decimal BuyPrice = decimal.MinValue;
            //买入日期
            string BuyData = string.Empty;
            //卖出价格
            decimal SellPrice = decimal.MinValue;
            //卖出时间
            string SellData = string.Empty;
            //盈利总和
            decimal Money = 0;
            //每次交易收益列表
            List<decimal> MyReturnList = new List<decimal>();
            //股价自然涨跌列表
            List<decimal> ObjectiveRetrunList = new List<decimal>();
            //交易详情
            string tradeinfo = string.Empty;
            //是否持仓
            bool iskeep = false;
            

            DateTime start = DateTime.ParseExact(LargeTList[0].ToString(), "yyyyMMdd", null);
            Dictionary<string, bool> iscando = new Dictionary<string, bool>();
            //获取大周期金叉区间
            for (int i = 0; i < LargeTList.Count; i++)
            {
                //获取SB点,判断短期线上穿长期线为true
                if (LargeLongList[i] < LargeShortList[i])
                {
                    while (start <= DateTime.ParseExact(LargeTList[i].ToString(), "yyyyMMdd", null))
                    {
                        iscando.Add(start.ToString("yyyyMMdd"), true);
                        start = start.AddDays(1);
                        
                    }
                }
                else if (LargeLongList[i] > LargeShortList[i])
                {
                    while (start <= DateTime.ParseExact(LargeTList[i].ToString(), "yyyyMMdd", null))
                    {
                        iscando.Add(start.ToString("yyyyMMdd"), false);
                        start = start.AddDays(1);
                    }
                }


                //如果昨天死叉且今天金叉，则买入，反之卖出,由于初始状态是true，true，只有第一次从死叉变金叉后，才会修改BuyPrice，此时为第一次买入
                //if (NowStatus == true && LastStatus == false)
                //{
                //    //忽略第一次交叉前的状态
                //    if (BuyPrice == decimal.MinValue)
                //    {
                //        FirstPrice = BenchmarkList[i];
                //    }
                //    BuyPrice = BenchmarkList[i];
                //    BuyData = SmallTList[i].ToString();
                //}
                //else if (NowStatus == false && LastStatus == true)
                //{
                //    SellPrice = BenchmarkList[i];
                //    if (BuyPrice != decimal.MinValue)
                //    {
                //        Money += SellPrice - BuyPrice;
                //        tradeinfo += "买入：" + BuyData + "/" + BuyPrice + "---卖出：" + SmallTList[i] + "/" + SellPrice.ToString() + "---盈利：" + Money.ToString() + "\n";
                //    }
                //}
                //更新昨天交叉状态
            }



            
            for (int i = 0; i < SmallTList.Count; i++)
            {
                //获取SB点,判断短期线上穿长期线为true
                if (SmallLongList[i] < SmallShortList[i])
                {
                    NowStatus = true;
                }
                else if (SmallLongList[i] > SmallShortList[i])
                {
                    NowStatus = false;
                }

                //如果昨天死叉且今天金叉，则买入，反之卖出
                //由于初始状态是true，true，只有经历过一次死叉后，LastStatus才为false，所以当前if是经历过死叉后的金叉，可进行交易。
                if (NowStatus == true && LastStatus == false)
                {
                    if (iskeep == false && iscando[SmallTList[i].ToString()] == true)
                    {
                        if (BuyPrice == decimal.MinValue)
                        {
                            FirstPrice = CloseList[i];
                        }
                        BuyPrice = BenchmarkList[i];
                        BuyData = SmallTList[i].ToString();
                        iskeep = true;
                    }
                    
                }
                else if (NowStatus == false && LastStatus == true)
                {
                    SellPrice = BenchmarkList[i];
                    //如果从来没有买过，死叉也不做交易，避免默认LastStatus=true带来的问题
                    if (BuyPrice != decimal.MinValue)
                    {
                        if (iskeep == true)
                        {
                            Money += SellPrice - BuyPrice;
                            tradeinfo += "买入：" + BuyData + "/" + BuyPrice + "---卖出：" + SmallTList[i] + "/" + SellPrice.ToString() + "---盈利：" + Money.ToString() + "\r\n";
                            iskeep = false;
                        }
                        
                    }
                }
                else
                {
                    //(true,true)可能是初始状态，也可能是金叉范围内
                    //(false,false)是死叉范围内
                    //两种情况均不作处理
                }
                //更新昨天交叉状态
                LastStatus = NowStatus;

                //记录累计收益
                if (BuyPrice == decimal.MinValue)
                {
                    MyReturnList.Add(CloseList[i]);
                }
                else
                {
                    MyReturnList.Add(FirstPrice + Money);
                }

                ObjectiveRetrunList.Add(CloseList[i]);

            }
            tradeinfo += "收益率：" + Math.Round((FirstPrice == 0 ? 0 : (Money / FirstPrice * 100)), 2) + "%\r\n";
            tradeinfo += "自然涨跌：" + Math.Round((ObjectiveRetrunList[ObjectiveRetrunList.Count - 1] - ObjectiveRetrunList[0]) / ObjectiveRetrunList[0] * 100, 2) + "%\r\n";

            var result = new TotalResult
            {
                TradeInfo = tradeinfo,
                TList = SmallTList,
                StockPriseList = ObjectiveRetrunList,
                StockReturnList = MyReturnList,
                MyTotalReturn = Math.Round((FirstPrice == 0 ? 0 : (Money / FirstPrice * 100)), 2) + "%",
                ObjectiveTotalReturn = Math.Round((ObjectiveRetrunList[ObjectiveRetrunList.Count - 1] - ObjectiveRetrunList[0]) / ObjectiveRetrunList[0] * 100, 2) + "%"
            };
            return result;
        }
    }
}
